package main

import (
	"fmt"
	"runtime"
)
/*
GO会在程序真正执行前对整个程序的依赖进行分析，并初始化相关的代码包
所有的代码包初始化函数都会在main函数（命令源码文件中的入口函数）之前执行完毕，而且只会执行一次
当前代码包中的所有全局变量的初始化会在代码包初始化函数执行前完成
这就避免了在代码包初始化函数对某个变量进行赋值之后又被该变量声明中赋予的值覆盖掉的问题
*/

//同一个代码包中，可以存在多个代码包初始化函数，甚至代码包内的每一个源码文件都可以定义多个代码包初始化函数
//Go编译器无法保证同一个代码包中的多个代码包初始化函数的执行顺序
// 如果确实需要按特定顺序执行的话，可以考虑使用GoLang并发编程模型中的channel进行控制
// 或者调整代码包初始化函数的顺序
func init(){
	println("this is other two init function()")
	if name != "" {
		println("my name is ",name)
	}else {
		println("name not is init")
	}
	name = "SteveRocket"
}


//GO中可以有专门的函数负责代码包的初始化   该函数无需参数声明和结果声明，且名称必须为init
//包初始化函数
func init(){  //第一条语句在执行时，变量m已经被初始化并赋值，说明当前代码包中所有全局变量的初始化会在代码包初始化函数执行前完成
	println("this is init function")
	fmt.Printf("Map result:%v\n", m)  //先格式化再打印
	info = fmt.Sprintf("OS:%s, Arch:%s", runtime.GOOS, runtime.GOARCH)
	//输出操作系统类型以及架构类型：OS:windows, Arch:amd64
}

//定义一个非全局变量  map类型  已被显示赋值
var m map[int]string = map[int]string{11:"AAA",22:"BBB",33:"CCC"}

//非全局变量  string类型  未被显示赋值
var info string  //info默认会被赋予类型string的零值 空字符串""
//var info string  //error 相同作用域下，不允许存在相同名字的全局变量
var name string

func init(){
	println("this is other one init function()")
	println("my name is ",name)
	name = "GoLang"
}



var sum int32
var result int32

func calc_sum(num1,num2 int32){
	//var sum int32  //定义在此处还出错
	sum = num1 + num2
	//return sum  //error
	//return num1 + num2  //error
}

//func calc_sum(num1,num2 int32){
//	'calc_sum' redeclared in this block less Reports names redeclared in this block.
//}

func main() {
	//init()  //此处不需要手动调用   main方法执行之前 init()方法会自动被调用
	//也就是说一个程序  main方法并不是优先执行的

	fmt.Println(info)

	//result = calc_sum(12,34)  //error
	calc_sum(12,34)

	//fmt.Println(calc_sum(12,34))  //这种直接输出的方式还出错
}
